home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Games / dinkum3 / parse.c < prev    next >
C/C++ Source or Header  |  1995-05-03  |  19KB  |  890 lines

  1. #define PARSE
  2. #include "dink_sym.h"
  3. #include "dink_glb.h"
  4. #include <string.h>
  5. #include <stdlib.h>
  6.  
  7. #if (PROTOTYPE)
  8. void parse(void)
  9. #else
  10. parse()
  11. #endif
  12. /*********************************************************/
  13. /*                                                       */
  14. /*      --- English Language Parsing Subroutine ---      */
  15. /*                                                       */
  16. /*  This subroutine parses a sentence of up to nineteen  */
  17. /*  words and decodes the words into integers and passes */
  18. /*  a twenty element vector back to the calling          */
  19. /*  program.  The digit 0, implies an unused word.  The  */
  20. /*  digit -1 (V_LINE_END), indicates end of sentence.    */
  21. /*                                                       */
  22. /*  This code was made portable to Apple MacIntosh       */
  23. /*  computers through the assistance of Paul Russel.     */
  24. /*                                                       */
  25. /*      Program by Gary A. Allen, Jr. 16 February 1993   */
  26. /*        (c) Copyright 1993 by Gary A. Allen, Jr.       */
  27. /*                                                       */
  28. /*********************************************************/
  29. {
  30. #if (PROTOTYPE)
  31. char getche(void) ;
  32. int synonym(int) ;
  33. void purge(int, int*) ;
  34. #else
  35. char getche() ;
  36. int synonym() ;
  37. #endif
  38.  
  39. register int i, j ;
  40.  
  41. int m, n, jacc, i_ws, sw_purge, j_purge, sw_loop, sw_decode ;
  42.  
  43. /* a sentence can have 19 words of 15 letters */ 
  44. char words[20][15], word[15] ;
  45. char letter, buffer[300], *pnt ;
  46.  
  47. ADJECTIVE_STRUCT *adj ;
  48.  
  49. /* flush the "sent vector" */
  50. for (i = 0; i <= 19; i++) sent[i] = 0 ;
  51.  
  52. /* flush the tag vector */
  53. for (i = 0; i <= Vocab_cnt; i++) tag[i] = FALSE ;
  54.  
  55. /* Outer infinite "for" loop to parse and load in the words */
  56. for(;;) {
  57.  
  58. /* print prompt */
  59. /* This modification was suggested by Chris Herborth. */
  60. #ifdef PROMPT
  61. printf(">") ;
  62. #endif
  63.  
  64. /* Keyboard input "for" loop */
  65. for (i = 0; i <= 299; i++) {
  66.     if (Recorder->Status == S_playing) {
  67.         if (feof(fp)) {
  68.             Recorder->Status = S_inactive ;
  69.             continue ;
  70.         }
  71.         letter = fgetc(fp) ;
  72.         putchar(letter) ;
  73.     }
  74.     else {
  75. #ifndef __TURBOC__
  76.         letter = getchar() ;    
  77. #endif
  78. #ifdef __TURBOC__
  79.         letter = getche() ;    
  80. #endif
  81.         if (Recorder->Status == S_recording) {
  82.             if ((letter == '\n') || (letter == '\r')) {
  83.                 fprintf(fp,"\n") ;
  84.             }
  85.             else fputc(letter, fp) ;
  86.         }
  87.     }
  88.  
  89.     buffer[i] = letter ;
  90.  
  91.     /* First pass "switch" block */
  92.     switch(letter) {
  93.  
  94.     /* Carriage return */
  95.     case '\n':
  96.     case '\r':
  97.         break ;
  98.  
  99.     /* Backspace */
  100.     case '\b':
  101.         i -= 2 ;
  102.         if (i < 0) {
  103.             i = -1 ;
  104. #ifdef __TURBOC__
  105.             putchar('\a') ; /* ring bell */
  106. /* "{" --- this is to balance the parenthesis below for Vi */
  107.         }
  108.         putchar(' ') ;
  109.         putchar(0x08) ;
  110. #endif
  111. #ifndef __TURBOC__
  112.         }
  113. #endif
  114.         continue ;
  115.  
  116.     default:
  117.         continue ;
  118.     } /* end of the first pass "switch" block */
  119.     break ;
  120. } /* end of keyboard input "for" loop */
  121.  
  122. /* Deal with goofy long strings */
  123. if (i > 299) {
  124.     printf("\n\nHuh? That last sentence was a long one!\n") ;
  125.     printf("Try making it a bit shorter.\n\n") ;
  126.     continue ;
  127. }
  128.  
  129. sw_loop = FALSE ;
  130. sw_decode = FALSE ;
  131. pnt = buffer ;
  132.  
  133. /* Outer word counting "for" loop */
  134. for (i = 0; i <= 18; i++) {
  135.     /* Inner letter counting "for" loop */
  136.     for (j = 0; j <= 14; j++) {
  137.         /* Letter type "switch" block */
  138.         switch (letter = *(pnt++)) {
  139.             case '\n':
  140.             case '\r' :
  141.                 sw_loop = TRUE ;
  142.                 if ((i == 0) && (j == 0)) break ;
  143.                 words[i][j] = '\0' ;  
  144.                 sw_decode = TRUE ; 
  145.                 break ;
  146.  
  147.             /* White spaces and punctuation for cutting out words */
  148.             case '\"':
  149.             case ' ':
  150.             case ',':
  151.             case '.':
  152.             case ';':
  153.             case ':':
  154.             case '?':
  155.             case '!':
  156.             case '&':
  157.             case '{':
  158.             case '}':
  159.             case '[':
  160.             case ']':
  161.             case ')':
  162.             case '(':
  163.             case '\'':
  164.             case '`':
  165.             case '\t':
  166.                 words[i][j] = '\0' ;  
  167.                 break;
  168.  
  169.             default:
  170.                 words[i][j] = letter ;
  171.                 continue ;
  172.         } /* end of letter type "switch" block */
  173.         break ;
  174.     } /* end of inner letter counting "for" loop */
  175.     if (sw_loop) break ;
  176.     if (j > 14) {
  177. printf("\nYou're saying nonsense! Type the sentence again. \n");
  178.         break ;
  179.     }
  180.     if (j == 0) i-- ;
  181. } /* end of outer word counting "for" loop */
  182.  
  183. /* Bad sentence handling block */
  184. if (!sw_decode) {
  185.     if (sw_loop) continue ;
  186.  
  187.     if (i > 18) 
  188. printf ("\nYour sentence is too long. Type something shorter! \n") ;
  189.  
  190. #ifndef __TURBOC__
  191.     /* Purge the input buffer */
  192.     for (;;) if ('\n' == getchar()) break ;
  193. #endif
  194.  
  195.     continue ; /* resume the infinite "for" loop */
  196. } /* end of bad sentence handling block */
  197.  
  198. #ifdef __TURBOC__
  199. printf("\n") ;
  200. #endif
  201.  
  202. /* Decode the words from the known vocabulary */
  203. m = i ;
  204. jacc = 0;
  205. for (i = 0; i <= m; i++) {
  206.     for (j = 0; j <= 14; j++) {
  207.         word[j] = words[i][j] ; 
  208.     }
  209.     for (j = 0; j < Vocab_cnt; j++) {
  210.         n = strcmp(word,vocab[j]);
  211.         if (n == 0) {
  212.             if ((j > 9)&&(j < 20)) j -= 10;
  213.             sent[jacc++] = j + 1 ;
  214.             break; 
  215.         }
  216.     }
  217.     /* Deal with a number */
  218.     if ((word[0] >= 48)&&(word[0] <= 57)) {
  219.         tag[V_NUMBER] = TRUE ;
  220.         for (j = 0; j <= 14; j++) {
  221.             if ((word[j] < 48)||(word[j] > 57)) {
  222.                 if (word[j] != '\0') tag[V_NUMBER] = FALSE ;
  223.                 break ;
  224.             }
  225.         }
  226.         if (tag[V_NUMBER]) number_word = atoi(word) ;
  227.     }
  228. } /* end of vobaulary decode block */
  229.  
  230. if (jacc == 0) {
  231.     printf ("Huh? Nothing you said was understandable! Try again. \n");
  232.     continue ;
  233. }
  234.  
  235. /* mark last word */
  236. sent[jacc] = V_LINE_END ;
  237.  
  238. /* Check to see if this is a simple move command */
  239. if (sent[0] <= 10) {
  240.     tag[V_MOVE] = TRUE ;
  241.     tag[V_DIRECTION] = TRUE ;
  242.     verb = sent[0] ;
  243.     return ; 
  244. } /* end of the simple move block */
  245.  
  246. /* adjective and "in/out" preposition "for" loop */
  247. sw_purge = FALSE ;
  248. for (j = 0; j <= jacc-1; j++) {
  249.  
  250.     /* check for adjectives */
  251.     adj = adjective ;
  252.     for (i = 0; i < Adj_max; i++) {
  253.         if (sent[j] == adj->Adjective) {
  254.  
  255.         /* Does a noun have to be ignored ? */
  256.         if ((adj->Command == F_ignore)
  257.             && (adj->Modified_noun != sent[j+1])) break ;
  258.  
  259.         /* Does a noun have to be replaced? */
  260.         if ((adj->Command == F_replace)
  261.             && (adj->Modified_noun == sent[j+1])) {
  262.                 sent[j+1] = adj->Generated_noun ;
  263.         }
  264.         sw_purge = TRUE ;
  265.         j_purge = j ;
  266.         }
  267.         adj++ ;
  268.     } 
  269. } /* end of adjective and "in/out" preposition "for" loop */
  270.  
  271. /* purge processed adjective from sentence */
  272. if (sw_purge) purge(j_purge, &jacc) ;
  273.  
  274. /* Verb grammer check "for" loop */
  275. /* see if the sentence is of a command sentax */
  276. sw_loop = FALSE ;
  277. for (i = 0; i < Verb_max; i++) {
  278.     if (sent[0] == verb_table[i]) {
  279.         if (synonym(jacc)) {
  280.             sw_loop = TRUE ;
  281.             break ;
  282.         }
  283.         return ;
  284.     }
  285. } /* end of verb grammer check "for" loop */
  286. if (sw_loop) continue ;
  287.  
  288. /* First word is not a verb so check to see if this is a "question" sentence */
  289. /*    this logic can certainly be improved  */
  290. for (i = 0; i < Quest_max; i++) {
  291.     if (sent[0] == quest[i]) {
  292.         /* shift the sentence over and load in "question" */ 
  293.         for (j = jacc; j >= 0; j--) sent[j+1] = sent[j] ;
  294.         sent[0] = V_QUESTION ;
  295.         tag[V_QUESTION] = TRUE ; 
  296.         if (++jacc == 2) {
  297.         /* Sentence is a one word command */
  298.             tag[V_VERB_ONLY] = TRUE ;
  299.             tag[sent[1]] = TRUE ;
  300.             verb = V_QUESTION ;
  301.             return ;
  302.         }
  303.         if (synonym(jacc)) {
  304.             sw_loop = TRUE ;
  305.             break ;
  306.         }
  307.         return ;
  308.     } 
  309. } /* end of first word not a verb so check if "question" block */
  310. if (sw_loop) continue ;
  311.  
  312. /* This is not a question and the first word is --not-- a verb. */
  313. /*     Therefore a verb is embedded and must be swapped in. */
  314. if (jacc != 1) for (j = 1; j <= jacc-1; j++) {
  315.     /* Check to see if the word is a move command */
  316.     if (sent[j] <= 10) {
  317.         tag[V_MOVE] = TRUE ;
  318.         i_ws = sent[0] ;
  319.         sent[0] = sent[j] ;
  320.         sent[j] = i_ws ;
  321.         if (synonym(jacc)) {
  322.             sw_loop = TRUE ;
  323.             break ;
  324.         }
  325.         return ;
  326.     } /* end of simple move command block */
  327.  
  328.     /* if not a move command then check the verb table */
  329.     for (i = 0; i < Verb_max; i++) {
  330.         if (sent[j] == verb_table[i]) {
  331.             i_ws = sent[0] ;
  332.             sent[0] = sent[j] ;
  333.             sent[j] = i_ws ;
  334.             if (synonym(jacc)) {
  335.                 sw_loop = TRUE ;
  336.                 break ;
  337.             }
  338.             return ;
  339.         }
  340.     }
  341.     if (sw_loop) break ;
  342. } /* end of verb is embedded and must be swapped in block */
  343. if (sw_loop) continue ;
  344.  
  345. /* Verb error routine */
  346. printf ("If there was a verb in that sentence, I didn't understand ") ;
  347. printf ("it.\n") ;
  348.  
  349. } /* end of outer most infinite "for" loop to parse in the words */
  350.  
  351. } /* --- end of "parse" subroutine --- */
  352.  
  353.  
  354. #if (PROTOTYPE)
  355. int synonym(int jacc)
  356. #else
  357. int synonym(jacc)
  358. int jacc ;
  359. #endif
  360. /**************************************/
  361. /*                                    */
  362. /*         Synonym Function           */
  363. /*                                    */
  364. /* Version: Mk 1.0    6 December 1992 */
  365. /*                                    */
  366. /**************************************/
  367. {
  368. register int i, j ;
  369. int j_point ;
  370. int sw_movement, sw_adverb, sw_adverb_fnd ;
  371.  
  372. ADVERB_STRUCT *adv ;
  373.  
  374. #if (PROTOTYPE)
  375. void purge(int, int*) ;
  376. #endif
  377.  
  378. /* prescan for verb connected movement commands */
  379. switch(sent[0]) { 
  380. case V_go:
  381. case V_move:
  382. case V_walk:
  383. case V_run:
  384. case V_jump:
  385. case V_leap:
  386. case V_hop:
  387. case V_stroll:
  388. case V_saunter:
  389. case V_swagger:
  390.     sw_movement = TRUE ;
  391.     break ;
  392. default:
  393.     sw_movement = FALSE ;
  394. }
  395.  
  396. /* adverb scan, sent[0] is the verb */
  397. sw_adverb = FALSE ;
  398. sw_adverb_fnd = FALSE ;
  399. adv = adverb ;
  400. for (i = 0; i < Adv_max; i++) {
  401.     for (j = 1; j <= jacc-1; j++) {
  402.         /* see if this is an adverb */
  403.         if (sent[j] == adv->Adverb) {
  404.             j_point = j ;
  405.             sw_adverb = TRUE ;
  406.  
  407.             /* does the sentence have the companion verb? */
  408.             if (adv->Modified_verb == sent[0]) {
  409.                 sent[0] = adv->Generated_verb ;
  410.                 sw_adverb = FALSE ;
  411.                 sw_adverb_fnd = TRUE ;
  412.  
  413.             /* purge processed adverb from sentence */
  414.                 purge(j, &jacc) ;
  415.             }
  416.         }
  417.     }
  418.     adv++ ;
  419. }
  420.  
  421. /* purge unprocessed adverb from sentence */
  422. if (sw_adverb && (!sw_movement)) purge(j_point, &jacc) ;
  423.  
  424. /* scan the sentence for the movement direction */
  425. if ((!sw_adverb_fnd) && sw_movement) {
  426.     for (j = 0; j <= jacc-1; j++) {
  427.         if (sent[j] <= 10) {
  428.             tag[V_MOVE] = TRUE ;
  429.             tag[V_DIRECTION] = TRUE ;
  430.             verb = sent[j] ;
  431.             return(FALSE) ;
  432.         }
  433.         if (sent[j] == V_LINE_END) break ;
  434.     }
  435.     printf("Where to?  In what direction?\n") ;
  436.     return(TRUE) ;
  437.  
  438. tag[sent[0]] = TRUE ;  /* activate the tag for the verb */
  439.  
  440. if (jacc == 1) {
  441. /* Sentence is a one word command */
  442.     tag[V_VERB_ONLY] = TRUE ;
  443.     verb = sent[0] ;
  444.     if (sent[0] <= 4) return(FALSE) ; /* first 5 elements are reserved */
  445.     return(FALSE) ;
  446. }
  447.  
  448. /* Load the "tag" matrix for detected words and synonyms */
  449. for (j = 1; j <= 19; j++) {
  450.     if (sent[j] == V_LINE_END) break ;
  451.     if (sent[j] <= 10) tag[V_DIRECTION] = TRUE ;
  452.     if (sent[j] <= 4) continue ; /* first 5 elements are reserved */
  453.     tag[sent[j]] = TRUE ;  /* activate an element for each word */
  454.  
  455.     /* Deal with synonym nouns */
  456.     switch(sent[j]) {
  457.  
  458.     case V_automatic:
  459.     case V_AUTO:
  460.         tag[V_auto] = TRUE ;
  461.         continue ;
  462.  
  463.     case V_bar:
  464.         tag[V_gold] = TRUE ;
  465.         continue ;
  466.  
  467.     case V_beer:
  468.     case V_fourex:
  469.     case V_Fourex:
  470.         tag[V_can] = TRUE ;
  471.         continue ;
  472.  
  473.     case V_cockroaches:
  474.         tag[V_PLURAL] = TRUE ;
  475.         tag[V_cockroach] = TRUE ;
  476.         continue ;
  477.  
  478.     case V_diamond:
  479.         tag[V_ring] = TRUE ;
  480.         continue ;
  481.  
  482.     case V_doormat:
  483.         tag[V_mat] = TRUE ;
  484.         continue ;
  485.  
  486.     case V_drop:
  487.         tag[V_bear] = TRUE ;
  488.         continue ;
  489.  
  490.     case V_everything:
  491.         tag[V_all] = TRUE ;
  492.         continue ;
  493.  
  494.     case V_wall:
  495.         tag[V_warning] = TRUE ;
  496.         tag[V_message] = TRUE ;
  497.         continue ;
  498.  
  499.     case V_money:
  500.         tag[V_bill] = TRUE ;
  501.         continue ;
  502.  
  503.     case V_lager:
  504.         tag[V_bottle] = TRUE ;
  505.         continue ;
  506.  
  507.     case V_fuze:
  508.     case V_fuse:
  509.         tag[V_cap] = TRUE ;
  510.         continue ;
  511.  
  512.     case V_gleeps:
  513.         tag[V_PLURAL] = TRUE ;
  514.         tag[V_gleep] = TRUE ;
  515.         continue ;
  516.  
  517.     case V_hoop:
  518.         tag[V_snake] = TRUE ;
  519.         continue ;
  520.  
  521.     case V_M16:
  522.     case V_m16:
  523.     case V_gun:
  524.         tag[V_rifle] = TRUE ;
  525.         continue ;
  526.  
  527.     case V_kangaroos:
  528.         tag[V_PLURAL] = TRUE ;
  529.         tag[V_kangaroo] = TRUE ;
  530.         continue ;
  531.  
  532.     case V_magazine:
  533.     case V_ammo:
  534.         tag[V_clip] = TRUE ;
  535.         continue ;
  536.  
  537.     case V_mail:
  538.     case V_envelope:
  539.         tag[V_letter] = TRUE ;
  540.         continue ;
  541.  
  542.     case V_charts:
  543.     case V_schedule:
  544.     case V_schedules:
  545.         tag[V_chart] = TRUE ;
  546.         continue ;
  547.  
  548.     case V_matchbox:
  549.         tag[V_matches] = TRUE ;
  550.     case V_matches:
  551.         tag[V_PLURAL] = TRUE ;
  552.         tag[V_match] = TRUE ;
  553.         continue ;
  554.  
  555.     case V_Ned:
  556.     case V_kelly:
  557.     case V_Kelly:
  558.         tag[V_ned] = TRUE ;
  559.         continue ;
  560.  
  561.     case V_off_q:
  562.         tag[V_off] = TRUE ;
  563.         continue ;
  564.  
  565.     case V_on_q:
  566.         tag[V_on] = TRUE ;
  567.         continue ;
  568.  
  569.     case V_plan:
  570.         tag[V_map] = TRUE ;
  571.     case V_map:
  572.         tag[V_map_frag] = TRUE ;
  573.         continue ;
  574.  
  575.     case V_painting:
  576.         tag[V_picture] = TRUE ;
  577.         continue ;
  578.  
  579.     case V_picture:
  580.         tag[V_photo] = TRUE ;
  581.         continue ;
  582.  
  583.     case V_doors:
  584.         tag[V_PLURAL] = TRUE ;
  585.         tag[V_door] = TRUE ;
  586.         continue ;
  587.  
  588.     case V_pills:
  589.     case V_packet:
  590.         tag[V_PLURAL] = TRUE ;
  591.     case V_atropine:
  592.         tag[V_pill] = TRUE ;
  593.         continue ;
  594.  
  595.     case V_safety:
  596.     case V_SAFE:
  597.         tag[V_safe] = TRUE ;
  598.         continue ;
  599.  
  600.     case V_silver:
  601.         tag[V_coin] = TRUE ;
  602.         continue ;
  603.  
  604.     case V_spinifexes:
  605.         tag[V_PLURAL] = TRUE ;
  606.         tag[V_spinifex] = TRUE ;
  607.         continue ;
  608.  
  609.     case V_yourself:
  610.     case V_myself:
  611.         tag[V_self] = TRUE ;
  612.         continue ;
  613.  
  614.     case V_stick:
  615.     case V_explosive:
  616.         tag[V_dynamite] = TRUE ;
  617.         continue ;
  618.  
  619.     case V_switch:
  620.         tag[V_button] = TRUE ;
  621.         continue ;
  622.  
  623.     case V_treasure:
  624.         tag[V_all] = TRUE ;
  625.         continue ;
  626.  
  627.     case V_I:
  628.         tag[V_single] = TRUE ;
  629.         continue ;
  630.  
  631.     case V_III:
  632.         tag[V_triple] = TRUE ;
  633.         continue ;
  634.  
  635.     case V_zero:
  636.         tag[V_0] = TRUE ;
  637.         tag[V_NUMBER] = TRUE ;
  638.         number_word = 0 ;
  639.         continue ;
  640.  
  641.     case V_one:
  642.         tag[V_NUMBER] = TRUE ;
  643.         number_word = 1 ;
  644.         continue ;
  645.  
  646.     case V_two:
  647.         tag[V_NUMBER] = TRUE ;
  648.         number_word = 2 ;
  649.         continue ;
  650.  
  651.     case V_three:
  652.         tag[V_NUMBER] = TRUE ;
  653.         number_word = 3 ;
  654.         continue ;
  655.  
  656.     case V_four:
  657.         tag[V_NUMBER] = TRUE ;
  658.         number_word = 4 ;
  659.         continue ;
  660.  
  661.     case V_five:
  662.         tag[V_NUMBER] = TRUE ;
  663.         number_word = 5 ;  /* Dinkum doesn't count past 5 */
  664.         continue ;
  665.  
  666.     case V_forty_nine:
  667.         tag[V_49] = TRUE ;
  668.         continue ;
  669.  
  670.     case V_sixty_seven:
  671.         tag[V_67] = TRUE ;
  672.         continue ;
  673.  
  674.     case V_eighty_two:
  675.         tag[V_82] = TRUE ;
  676.         continue ;
  677.  
  678.     default:
  679.         continue ;
  680.     }
  681. } /* end of sentence tag word scan */
  682. verb = sent[0] ;
  683. return(FALSE) ;
  684.  
  685. } /* --- end of "synonym" subroutine --- */
  686.  
  687. #if (PROTOTYPE)
  688. void purge(int k_start, int *k_finish)
  689. #else
  690. purge(k_start, k_finish)
  691. int k_start, *k_finish ;
  692. #endif
  693. /***********************************/
  694. /*                                 */
  695. /*   Sentence Purging Subroutine   */
  696. /*                                 */
  697. /* Version: Mk 1.0  3 March 1990   */
  698. /*                                 */
  699. /***********************************/
  700. {
  701. register int k ;
  702. int k_end ;
  703.  
  704. k_end = *k_finish ;
  705. for (k = k_start; k <= k_end-1; k++) sent[k] = sent[k+1] ;
  706. *k_finish = --k_end ;
  707. } /* --- end of "purge" subroutine --- */
  708.  
  709. #if (PROTOTYPE)
  710. void filler(void)
  711. #else
  712. filler()
  713. #endif
  714. /***********************************/
  715. /*                                 */
  716. /*        Filler Subroutine        */
  717. /*                                 */
  718. /* Version: Mk 1.0  18 August 1989 */
  719. /*                                 */
  720. /***********************************/
  721. {
  722.  
  723. if (tag[V_VERB_ONLY]) {
  724.     printf("Fill what?\n") ;
  725.     return ;
  726. }
  727. if (tag[V_can]) {
  728.     if (Can->Location != B_have) 
  729. printf("You don't have the Fourex can in your possession!\n") ;
  730. else printf("I can't do it!  There's a hole in the can's bottom.\n") ;
  731.     return ;
  732. }
  733. if (tag[V_bottle]) {
  734.     if (Bottle->Location != B_have) 
  735. printf("You don't have the bottle in your possession!\n") ;
  736. else printf("I can't do it!  The bottle has a crack in it's bottom.\n");
  737.     return ;
  738. }
  739. printf("I can't fill that!\n") ;
  740. } /* --- end of the "filler" subroutine --- */
  741.  
  742. #if (PROTOTYPE)
  743. void looker(int n)
  744. #else
  745. looker(n)
  746. int n ;
  747. #endif
  748. /***********************************/
  749. /*                                 */
  750. /*        Looker Subroutine        */
  751. /*                                 */
  752. /* Version: Mk 1.0  18 August 1989 */
  753. /*                                 */
  754. /***********************************/
  755. {
  756. register int i ;
  757. int m, sw_no_see ;
  758.  
  759. OBJECT_STRUCT *pnt ;
  760. READ_STRUCT *point ;
  761.  
  762. #if (PROTOTYPE)
  763. void long_descp(int), describe(int), objlooker(int), gleeper(int) ;
  764. void actor(int), rdtxt(int) ;
  765. OBJECT_STRUCT* point_to_object(int) ;
  766. #else
  767. OBJECT_STRUCT* point_to_object() ;
  768. #endif
  769.  
  770. /* an isolated "look" means to just look at the room */
  771. if (tag[V_VERB_ONLY]) { 
  772.     /* Check for long description */
  773.     if ((room[n][M_rm_type] == T_was_long)||(n == R_lift_inside))
  774.        long_descp(n);
  775.     else describe (n) ;
  776.     objlooker(n) ; /* Check if there are objects in the room */
  777.     gleeper(n) ;   /* check for gleeps and update the gleep count */
  778.     /* describe unmovable action objects and status */
  779.     if (room[n][M_unmov_obj]) actor(n) ;
  780.     return ;
  781. }
  782.  
  783. /* Gleep tank */
  784. if (tag[V_tank]) {
  785.     if (n == R_gleep_tank) {
  786. printf("You look inside the gleep tank and see a blue fluid which\n") ;
  787. printf("smells of chlorine") ;
  788.         if (Tank->Status == 0) {
  789. printf(".\n") ;
  790.             return ;
  791.         }
  792.         if (Tank->Status == 1) {
  793. printf(" and a single gleep submerged in the fluid.\n") ;
  794.             return ;
  795.         }
  796. printf(" and %d gleeps submerged in the fluid.\n",
  797.         Tank->Status) ;
  798.         return ;
  799.     }
  800.     else {
  801.         printf("There is no gleep tank here!\n") ;
  802.         return ;
  803.     }
  804. }
  805.  
  806. sw_no_see = FALSE ;
  807. point = read_object ;
  808. for (i = 0; i < Read_objcnt; i++) {
  809.     m = (point++)->ID ;
  810.     if (tag[m]) {
  811.         pnt = point_to_object(m) ;
  812.         if (pnt->Type == Z_unmovable) {
  813.             if (pnt->Location == n) {
  814.                 rdtxt(m) ;
  815.                 return ;
  816.             }
  817.             else sw_no_see = TRUE ;
  818.         }
  819.         else {
  820.             if (pnt->Location == B_have) rdtxt(m) ;
  821.             else 
  822. printf("I can examine an object only if it is in my possession.\n");
  823.             return ;
  824.         }
  825.     }
  826. }
  827. if (sw_no_see) {
  828.     printf("I don't see it here.\n") ;
  829.     return ;
  830. }
  831.  
  832. /* Deal with unreadable objects */
  833. printf("There is nothing more that I can describe about it.\n");
  834. return ;
  835.  
  836. } /* --- end of the "looker" subroutine --- */
  837.  
  838. #if (PROTOTYPE)
  839. void pass(void)
  840. #else
  841. pass()
  842. #endif
  843. /***********************************/
  844. /*                                 */
  845. /*        Password Subroutine      */
  846. /*                                 */
  847. /* Version: Mk 1.0  29 July 1989   */
  848. /*                                 */
  849. /***********************************/
  850. {
  851. register int i ;
  852. char chr ;
  853. static char *passwd = "2Xngootx7Ysd4Du9" ;
  854.  
  855. #if (PROTOTYPE)
  856. void exit(int);
  857. char getch(void) ;
  858. #else
  859. char getch() ;
  860. #endif
  861.  
  862. /* Request password */
  863. printf("Enter password:  ") ;
  864.  
  865. #ifndef __TURBOC__
  866. for (i = 2; i <= 7; i++) {
  867.     chr = getchar() ;
  868.     if (chr+i-1 != passwd[i]) exit(0) ;
  869. }    
  870. if (getchar() != '\n') exit(0) ;
  871. printf(".\n") ;  /* indicate that the password was accepted */
  872. #endif
  873.  
  874. #ifdef __TURBOC__
  875. for (i = 2; i <= 7; i++) {
  876.     chr = getch() ;
  877.     if (chr+i-1 != passwd[i]) { 
  878.         for (;;) if (getch() == 3) break ;
  879.         printf("\r                    \n") ;
  880.         exit(0) ;
  881.     }
  882. }
  883. printf("\r.                     \n") ;
  884. #endif
  885.  
  886. sw_wizard = TRUE ; /* toggle wizard switch */
  887.  
  888. } /* --- end of the "pass" subroutine */
  889.